1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <cstdio> #include <queue> #include <algorithm> #include <cstring> #define MP make_pair using namespace std; const int INF = 0x3f3f3f3f; int n, m, a[105], K = 0; int f[105][(1 << 11)]; pair <int, int> pre[105][(1 << 11)]; queue <int> q; bool inq[105]; const int dx[4] = {0, 0, 1, -1}; const int dy[4] = {1, -1, 0, 0}; void SPFA(int R){ while (!q.empty()){ int cur = q.front(); q.pop(); inq[cur] = 0; int x = cur / m, y = cur % m; for (int d = 0; d < 4; d++){ int v = m * (x + dx[d]) + y + dy[d]; if (x + dx[d] < 0 || x + dx[d] >= n || y + dy[d] < 0 || y + dy[d] >= m) continue; if (f[v][R] > f[cur][R] + a[v]){ f[v][R] = f[cur][R] + a[v]; pre[v][R] = MP(cur, R); if (!inq[v]) q.push(v), inq[v] = 1; } } } } int ans[105]; void dfs(int cur, int s){ if (!pre[cur][s].second) return; ans[cur] = 1; if (pre[cur][s].first == cur) dfs(cur, s ^ pre[cur][s].second); dfs(pre[cur][s].first, pre[cur][s].second); } int main(){ freopen("1.in", "r", stdin); scanf("%d%d", &n, &m); memset(f, 0x3f, sizeof f); int tmp; for (int i = 0; i < n * m; i++){ scanf("%d", a + i); if (a[i] == 0) f[i][(1 << (K++))] = 0, tmp = i; } for (int s = 1; s < (1 << K); s++){ for (int i = 0; i < n * m; i++){ for (int t = s & (s - 1); t; t = s & (t - 1)){ if (f[i][s] > f[i][t] + f[i][s ^ t] - a[i]){ f[i][s] = f[i][t] + f[i][s ^ t] - a[i]; pre[i][s] = MP(i, t); } } if (f[i][s] != INF) q.push(i), inq[i] = 1; } SPFA(s); } printf("%d\n", f[tmp][(1 << K) - 1]); dfs(tmp, (1 << K) - 1); for (int i = 0; i < n * m; i++){ if (a[i] == 0) putchar('x'); else if (ans[i]) putchar('o'); else putchar('_'); if ((i + 1) % m == 0) puts(""); } return 0; }
|